Completed
Push — master ( cf46b7...d90db3 )
by greg
02:24
created

prepare.js ➔ addAbeAttrForBlock   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
nc 2
nop 3
dl 0
loc 20
rs 9.4285
1
import Handlebars from 'handlebars'
2
import striptags from 'striptags'
3
4
import {
5
  cmsData
6
  ,config
7
  ,cmsTemplates
8
} from '../../'
9
10
export function addAbeAttrSingleTab(key, elem, htmlAttribute = null) {
11
  var res = ''
12
13
  var valueOfAttritube = key.replace(/\./g, '-')
14
  key = cmsData.regex.validDataAbe(valueOfAttritube)
15
  
16
  if (htmlAttribute != null) {
17
    res = ' data-abe-attr-' + valueOfAttritube + '="'  + htmlAttribute + '"' + ' data-abe-' + valueOfAttritube + '="'  + key + '"' + elem
18
  }else {
19
    res = ' data-abe-' + key + '="'  + key + '" ' + elem
20
  }
21
22
  return res
23
}
24
25
export function addAbeAttrForBlock(key, elem, htmlAttribute = null) {
26
  var res = ''
27
28
  var valueOfAttritube = key.split('.')
29
  var parentKey = valueOfAttritube.shift()
30
  valueOfAttritube = `${parentKey}[index].${valueOfAttritube[0].replace(/\./g, '-')}`
31
  var valueOfAttritubeIndexed = valueOfAttritube.replace(/\[index\]/, '{{@index}}')
32
  key = cmsData.regex.validDataAbe(valueOfAttritube)
33
34
  if (htmlAttribute) {
35
36
    res = ` data-abe-attr-${valueOfAttritube}="${htmlAttribute}"  data-abe-${valueOfAttritube}="${key}"`
37
      + ` data-abe-attr-${valueOfAttritubeIndexed}="${htmlAttribute}" data-abe-${valueOfAttritubeIndexed}="${key}"${elem}`
38
  }else {
39
    res = ` data-abe-${valueOfAttritube}="${key}"`
40
      + ` data-abe-${valueOfAttritubeIndexed}="${key}" ${elem}`
41
  }
42
43
  return res
44
}
45
46
/**
47
 * THIS:
48
<span>{{abe type='text' key='text_visible'}}</span>
49
50
 * BECOME:
51
<span data-abe-text_visible="text_visible" >{{abe type='text' key='text_visible'}}</span>
52
53
 * @param {[type]} template [description]
54
 */
55
export function addAbeDataAttrForHtmlTag(template) {
56
  var match
57
  var key
58
  var getattr
59
  var newTemplate = template
60
61
  while (match = cmsData.regex.abePattern.exec(template)) {
62
    key = cmsData.regex.getAttr(match, 'key')
63
64
    if (!cmsData.regex.isSingleAbe(match, newTemplate)) {
65
      key = key.replace('.', '{{@index}}.')
66
    }
67
68
    getattr = key.replace(/\./g, '-')
69
70
    newTemplate = newTemplate.replace(
71
      cmsData.regex.escapeTextToRegex(match[0], 'g'),
72
      ' data-abe-' + cmsData.regex.validDataAbe(getattr) + '="'  + getattr + '" ' + match[0]
73
    )
74
  }
75
76
  return newTemplate
77
}
78
79
export function addHasAbeAttr(text) {
80
  return text.replace('}}', ' has-abe=1}}')
81
}
82
83
export function getAbeAttributeData(match, text, htmlAttribute, abeTag) {
84
  var valueOfAttritube
0 ignored issues
show
Unused Code introduced by
The variable valueOfAttritube seems to be never used. Consider removing it.
Loading history...
85
  var key = cmsData.regex.getAttr(match, 'key')
86
  var res
87
88
  if (cmsData.regex.isSingleAbe(match, text)) {
89
    // valueOfAttritube = key.replace(/\./g, '-')
90
    // key = cmsData.regex.validDataAbe(valueOfAttritube)
91
    // key = key.replace(/\./g, '-')
92
    // res = ' data-abe-attr-' + valueOfAttritube + '="'  + htmlAttribute + '"' + ' data-abe-' + valueOfAttritube + '="'  + key + '"' + abeTag
93
    res = addAbeAttrSingleTab(key, abeTag, htmlAttribute)
94
  }else {
95
    res = addAbeAttrForBlock(key, abeTag, htmlAttribute)
96
    // valueOfAttritube = key.split('.')
97
    // var parentKey = valueOfAttritube.shift()
98
    // valueOfAttritube = `${parentKey}[index].${valueOfAttritube[0]}`
99
    // var valueOfAttritubeIndexed = valueOfAttritube.replace(/\[index\]/, '{{@index}}')
100
    // key = cmsData.regex.validDataAbe(valueOfAttritube)
101
102
    // res = ` data-abe-attr-${valueOfAttritube}="${htmlAttribute}"  data-abe-${valueOfAttritube}="${key}"`
103
    // + ` data-abe-attr-${valueOfAttritubeIndexed}="${htmlAttribute}" data-abe-${valueOfAttritubeIndexed}="${key}"${abeTag}`
104
  }
105
106
  return res
107
}
108
109
/**
110
 *
111
 * IF ABE TAG SINGLE (NOT ABE EACH STATEMENT)
112
 * 
113
 * THIS:
114
<img src="{{abe type='image' key='image_key' tab='default'}}" alt="">
115
116
 * BECOME:
117
<img data-abe-attr-image_key="src" data-abe-image_key="image_key" data-abe-attr-image_key="src"
118
data-abe-image_key="image_key" src="{{abe type='image' key='image_key' tab='default' has-abe=1 has-abe=1}}" alt="">
119
120
 *
121
 * IF ABE EACH TAG
122
 * THIS:
123
{{#each test}}
124
  <img src="{{abe type='image' key='test.img' desc='test_img' tab='default'}}" alt="">
125
{{/each}}
126
127
 * BECOME:
128
{{#each test}}
129
  <img data-abe-attr-test[index].img="src" data-abe-test[index].img="test[index].img" src="{{abe type='image' key='test.img' desc='test_img' tab='default' has-abe=1}}" alt="">
130
{{/each}}
131
132
 * @param {[type]} template [description]
133
 */
134
export function addAbeDataAttrForHtmlAttributes(template) {
135
  var text = template.replace(/<([A-Za-z]+)/g, '\nABE_SPLIT<$1')
136
  let abeTagIntoAttribute = text.match(cmsData.regex.abeAsAttributePattern)
137
138
  if (abeTagIntoAttribute != null) {
139
    Array.prototype.forEach.call(abeTagIntoAttribute, (abeIntoTag) => {
140
      let matchAbeTag = /({{abe.*?[\s\S].*?}})/g.exec(abeIntoTag)
141
142
      if(matchAbeTag != null && matchAbeTag[1] != null) {
143
        var toReplace = cmsTemplates.prepare.getAbeAttributeData(matchAbeTag[1], text, (abeIntoTag.split('=')[0]).trim(), abeIntoTag)
144
145
        toReplace = toReplace.replace(
146
          cmsData.regex.escapeTextToRegex(matchAbeTag[1]),
147
          cmsTemplates.prepare.addHasAbeAttr(matchAbeTag[1])
148
        )
149
150
        text = text.replace(
151
          cmsData.regex.escapeTextToRegex(abeIntoTag),
152
          toReplace
153
        )
154
      }
155
    })
156
  }
157
  text = text.replace(/\nABE_SPLIT</g, '<')
158
159
  return text
160
}
161
162
/**
163
 * Example:
164
 *
165
 *
166
 * THIS:
167
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
168
169
{{#each data_key}}
170
  {{title}}
171
{{/each}}
172
173
 *
174
 * BECOME THIS
175
176
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
177
178
{{#each data_key}}
179
  {{title}}
180
{{/each}}<!-- [[data_key]] %7B%7B%23each%20data_key%7D%7D%0A%09%7B%7Btitle%7D%7D%0A%7B%7B/each%7D%7D -->
181
182
 * @param {[type]} template [description]
183
 * @param {[type]} json     [description]
184
 */
185
export function addAbeSourceComment(template, json) {
186
187
  if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
188
    var keys = Object.keys(json.abe_source)
189
    
190
    for(var i in keys) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
191
      var replaceEach = new RegExp(`<!-- \\[\\[${keys[i]}\\]\\][\\s\\S]*?-->`, 'g')
192
      var regexEachKey = new RegExp(`{{#each ${keys[i]}}}`, 'g')
0 ignored issues
show
Unused Code introduced by
The variable regexEachKey seems to be never used. Consider removing it.
Loading history...
193
      template = template.replace(replaceEach, '')
194
195
      var patAttrSource = new RegExp(' ([A-Za-z0-9\-\_]+)=["|\'].*?({{' + keys[i] + '}}).*?["|\']', 'g')
196
      var patAttrSourceMatch = template.match(patAttrSource)
197
198
      if(patAttrSourceMatch != null) {
199
        let checkEscapedRegex = /["|'](.*?)["|']/
200
        let patAttrSourceInside = new RegExp('(\\S+)=["\']?((?:.(?!["\']?\\s+(?:\\S+)=|[>"\']))+.)["\']?({{' + keys[i] + '}}).*?["|\']', 'g')
201
        Array.prototype.forEach.call(patAttrSourceMatch, (pat) => {
202
          let patAttrSourceCheck = patAttrSourceInside.exec(pat)
203
          if(patAttrSourceCheck != null) {
204
            
205
            let checkEscaped = checkEscapedRegex.exec(patAttrSourceCheck[0])
206
            if(checkEscaped != null && checkEscaped.length > 0) {
207
              checkEscaped = escape(checkEscaped[1])
208
              template = template.replace(
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the for-each loop for example by template.replace(replaceEach, "") on line 193. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
209
                patAttrSourceCheck[0],
210
                ` data-abe-attr="${patAttrSourceCheck[1]}" data-abe-attr-escaped="${checkEscaped}" data-abe="${keys[i]}" ${patAttrSourceCheck[0]}`
0 ignored issues
show
introduced by
The variable i is changed by the for-each loop on line 190. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
211
              )
212
            }
213
          }
214
        })
215
      }
216
217
      var eachSource = new RegExp(`({{#each ${keys[i]}}[\\s\\S a-z]*?{{\/each}})`, 'g')
218
      var matches = template.match(eachSource)
219
      if(typeof matches !== 'undefined' && matches !== null) {
220
        Array.prototype.forEach.call(matches, (match) => {
221
          template = template.replace(match, `${match}<!-- [[${keys[i]}]] ${cmsTemplates.encodeAbeTagAsComment(match)} -->`)
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the for-each loop for example by template.replace(replaceEach, "") on line 193. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
introduced by
The variable i is changed by the for-each loop on line 190. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
222
        })
223
      }
224
    }
225
  }
226
227
  return template
228
}
229
230
/**
231
 * THIS:
232
<span>{{abe type='text' key='text_visible'}}</span>
233
234
 * BECOME:
235
<span><abe>{{abe type='text' key='text_visible'}}</abe></span>
236
237
 * @param {[type]} template [description]
238
 */
239
export function addAbeHtmlTagBetweenAbeTags(template) {
240
  var match
241
  var templateNoDom = striptags(template)
242
  
243
  // {{#each tags may be declared outside of an html Tag}}
244
  while (match = cmsData.regex.eachBlockPattern.exec(template)) {
245
    template = template.replace(cmsData.regex.escapeTextToRegex(match[1], 'g'), '<abe>' + match[1].trim() + '</abe>')
246
  }
247
  
248
  while (match = cmsData.regex.abeAsTagPattern.exec(templateNoDom)) {
249
    template = template.replace(cmsData.regex.escapeTextToRegex(match[1], 'g'), '<abe>' + match[1].trim() + '</abe>')
250
  }
251
252
  return template
253
}
254
255
/**
256
 * THIS:
257
[index].
258
259
 * BECOME:
260
{{@index}}-
261
262
 *  @param  {[type]} template [description]
263
 * @return {[type]}          [description]
264
 */
265
export function replaceAbeEachIndex(template) {
266
  return template.replace(/\[index\]\./g, '{{@index}}-')
267
}
268
269
export function removeHiddenAbeTag(template) {
270
  return template.replace(/(\{\{abe.*visible=[\'|\"]false.*\}\})/g, '')
271
}
272
273
/**
274
 * Remove {{abe type=*}} from html if attribute visible="false"
275
 * @param  {[type]} template [description]
276
 * @return {[type]}          [description]
277
 */
278
export function removeHandlebarsRawFromHtml(template) {
279
  return template.replace(/\{\{\{\{\/?raw\}\}\}\}/g, '')
280
}
281
282
/**
283
 * split {{#each}}...{{/each}} into an array
284
 * 
285
 * @param  {[type]} template [description]
286
 * @return {[type]}          [description]
287
 */
288
export function splitEachBlocks(template) {
289
  var block
290
  var blocks = []
291
292
  while (block = cmsData.regex.blockPattern.exec(template)) {
293
    blocks.push(block[1])
294
  }
295
296
  return blocks
297
}
298
299
export function indexEachBlocks(template, json, onlyHtml) {
300
  // create an array of {{each}} blocks
301
  var blocks = cmsTemplates.prepare.splitEachBlocks(template)
302
303
  Array.prototype.forEach.call(blocks, (block) => {
304
    var key = block.match(/#each (.*)\}\}/)[1]
305
    var match
306
307
    if(!onlyHtml) {
308
309
      var voidData = {}
310
      voidData[key] = [{}]
311
      var blockCompiled = Handlebars.compile(block.replace(/{{abe (.*?["']) ?}}/g, '[[abe $1]]').replace(new RegExp(`\\.\\.\/${config.meta.name}`, 'g'), config.meta.name))
312
      var blockHtml = blockCompiled(voidData, {data: {intl: config.intlData}}).replace(/\[\[abe (.*?)\]\]/g, '{{abe $1}}')
313
314
      // je rajoute un data-abe-block avec index sur tous les tags html du bloc each
315
      var textEachWithIndex = block.replace(/(<(?![\/])[A-Za-z0-9!-]*)/g, '$1 data-abe-block="' + key + '{{@index}}"')
316
317
      // I add an each block commentary only if the each block key != key of a type=data abe tag
318
      var keys = []
319
      if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
320
        keys = Object.keys(json.abe_source)
321
      }
322
      if(keys.indexOf(key) === -1){
323
        template = template.replace(block, textEachWithIndex + `<!-- [[${key}]] ${cmsTemplates.encodeAbeTagAsComment(blockHtml)} -->`)
324
      }
325
    }
326
327
    // Pour chaque tag Abe
328
    while (match = cmsData.regex.abeTag.exec(block)) {
329
      template = cmsTemplates.prepare.addAbeDictionnary(template, match[0], key)
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the while loop for example by cmsTemplates.prepare.add...template, match.0, key) on line 329. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
330
    } 
331
  })
332
333
  return template
334
}
335
336
/**
337
 * split {{#each}}...{{/each}} into an array
338
 *
339
 * THIS:
340
  {{abe type='text' key='test.title' desc='test title' tab='default'}}
341
342
 * BECOME THIS:
343
  {{abe dictionnary='test' type='text' key='test.title' desc='test title' tab='default'}}
344
345
 * 
346
 * @param  {[type]} template [description]
347
 * @return {[type]}          [description]
348
 */
349
export function addAbeDictionnary(template, match, key) {
350
  if(cmsData.regex.isEachStatement(match)) return
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
351
352
  if(cmsData.regex.isBlockAbe(match)){
353
    var abeDictionnary = match.replace(new RegExp('(key=[\'|"])' + key + '.', 'g'), '$1' + key + '[index].')
354
                               .replace(/\{\{abe/, '{{abe dictionnary=\'' + key + '\'')
355
356
    template = template.replace(match, abeDictionnary)
357
  }
358
359
  return template
360
}
361